import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

user_item_data = [
    [101, 2001, "2025-08-20", 4.5],
    [101, 2003, "2025-08-22", 3.8],
    [102, 2002, "2025-08-21", 5.0],
    [103, 2001, "2025-08-23", 4.2],
    [103, 2003, "2025-08-24", 3.5],
    [104, 2002, "2025-08-22", 4.0],
    [104, 2004, "2025-08-23", 4.7],
]
#user_item_data = pandas.read_csv('user.csv')
df = pd.DataFrame(
    user_item_data,
    columns=["user_id", "item_id", "time", "rating"]
)
# print(df)
users = df["user_id"].unique()#获取所有用户id

items = df["item_id"].unique()#获取所有商品id
# print("users:", users)
# print("items:", items)
rating_matrix = np.zeros((len(users), len(items)))
# print(rating_matrix)
for user_idx, user in enumerate(users):
    for item_idx, item in enumerate(items):
        # 提取评分（无交互则为0）
        rating = df[
            (df["user_id"] == user) & (df["item_id"] == item)
        ]["rating"].values
        rating_matrix[user_idx, item_idx] = rating[0] if len(rating) > 0 else 0
print(rating_matrix)
user_similarity = cosine_similarity(rating_matrix)
print(user_similarity,111111111)
k_similar_users = 2  # 取Top - 2相似用户
user_to_similar_users = {}
for user_idx, user in enumerate(users):
    similarity_scores = user_similarity[user_idx]
    print("similarity_scores:",similarity_scores)
    # 排序：从高到低，取Top - k（跳过自身，下标0是自己）
    similar_user_indices = np.argsort(similarity_scores)[::-1][1: k_similar_users + 1]
    print("similar_user_indices:",similar_user_indices)
    similar_users = [
        (users[idx], similarity_scores[idx])
        for idx in similar_user_indices
    ]
    user_to_similar_users[user] = similar_users
print(user_to_similar_users)
def recommend_for_user(user_id, top_n=3):
    target_user_idx = np.where(users == user_id)[0][0]
    print("target_user_idx:",target_user_idx)
    target_user_ratings = rating_matrix[target_user_idx]
    print("target_user_ratings:",target_user_ratings)
    unrated_item_indices = np.where(target_user_ratings == 0)[0]
    print("unrated_item_indices:",unrated_item_indices)
    unrated_items = items[unrated_item_indices]
    print("unrated_items:",unrated_items)

    if not unrated_items.size:
        return []  # 目标用户已交互所有物品，无推荐

    # 2. 找到相似用户
    similar_users = user_to_similar_users.get(user_id, [])
    if not similar_users:
        return []  # 无相似用户，无法推荐

    # 3. 收集相似用户对未交互物品的评分，按相似度加权
    item_scores = {}
    for sim_user_id, sim_score in similar_users:
        sim_user_idx = np.where(users == sim_user_id)[0][0]

        sim_user_ratings = rating_matrix[sim_user_idx]


        for item_idx, item in enumerate(unrated_items):
            item_global_idx = np.where(items == item)[0][0]

            item_rating = sim_user_ratings[item_global_idx]
            if item_rating > 0:  # 相似用户对该物品有评分
                weighted_score = sim_score * item_rating
                if item not in item_scores or weighted_score > item_scores[item]:
                    item_scores[item] = weighted_score

    # 4. 按加权得分排序，取Top - N
    sorted_items = sorted(
        item_scores.items(),
        key=lambda x: x[1],
        reverse=False
    )[:top_n]

    return sorted_items
print("=== 基于用户协同过滤为用户101推荐的物品 ===")
recommendations = recommend_for_user(101, top_n=3)
for item_id, score in recommendations:
    print(f"物品ID: {item_id}, 推荐得分: {score:.2f}")
abc = recommend_for_user(101)
print(abc)